package com.gaoxk.interceptor;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
import java.util.List;

/**
 * 权限验证拦截器：检查请求头中的Token
 */
@Component
public class AuthInterceptor extends AbstractSoapInterceptor {

    // 指定在"调用业务方法前"阶段执行
    public AuthInterceptor() {
        super(Phase.PRE_INVOKE);
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        try {
            // 从SOAP头中获取Token
            String token = getTokenFromHeader(message);
            
            // 验证Token（实际应调用认证服务）
            if (token == null || !"VALID_TOKEN".equals(token)) {
                // 验证失败，抛出SOAP错误
                throw new Fault(new Exception("权限验证失败：无效的Token"));
            }
            System.out.println("权限验证通过");
        } catch (Fault e) {
            throw e; // 直接抛出已包装的SOAP错误
        } catch (Exception e) {
            throw new Fault(new Exception("权限拦截器处理失败", e));
        }
        /*
        SoapFault fault = new SoapFault(
                "账号格式错误，必须为16位数字",
                new QName("http://schemas.xmlsoap.org/soap/envelope/", "Client", "soap")
        );

        // 添加自定义错误详情（会被序列化为XML的<detail>元素）
        AccountErrorDetail detail = new AccountErrorDetail();
        detail.setInvalidField("accountNo");
        detail.setRule("必须为16位数字");
        detail.setReceivedValue(request.getAccountNo());
        fault.setDetail(detail);

        throw fault;

         */
    }

    // 从SOAP Header中提取Token
    private String getTokenFromHeader(SoapMessage message) {
        List<Header> headers = message.getHeaders();
        QName tokenQName = new QName("http://your-company.com/auth", "Token");
        
        for (Header header : headers) {
            if (tokenQName.equals(header.getName())) {
                Element tokenElement = (Element) header.getObject();
                return tokenElement.getTextContent();
            }
        }
        return null;
    }
}
